﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Timer
{
    public enum TimePart
    {
        MilliSeconds = 0,
        Seconds = 1,
        Minutes = 2
    }

    

    public struct TomatoTime
    {
        private const int MILLISECONDS_IN_MINUTES = 60000;

        public TimeSpan WorkTime
        {
            get;
            private set;
        }
        public TimeSpan RestTime
        {
            get;
            private set;
        }

        public TimePart Unit
        {
            get;
            private set;
        }

        public TomatoTime(TimeSpan workTime, TimeSpan restTime)
            : this()
        {
            WorkTime = workTime;
            RestTime = restTime;
            Unit = TimePart.MilliSeconds;
        }

       

        
        public void DecrementWorkTimeSecond()
        {

            WorkTime = WorkTime.Subtract(TimeSpan.FromSeconds(1));
            
        }

        public void DecrementRestTimeSecond()
        {
            RestTime = RestTime.Subtract(TimeSpan.FromSeconds(1));
        }
    }

    
    

    public class TomatoTimer
    {
        private TomatoTime _intervalTime;

        private TomatoTime _currentTime;

        

        public bool IsStarted
        {
            get;
            private set;
        }

        private System.Timers.Timer _secondTimer;


        public event EventHandler<TomatoTimerElapsedEventArgs> Tick;

        public event EventHandler WorkEnded;
        public event EventHandler RestEnded;

        public TomatoTimer()
        {
            _intervalTime = new TomatoTime(TimeSpan.FromMinutes(25), TimeSpan.FromMinutes(5));
            Init();
        }

        public TomatoTimer(double workTime, double restTime)
        {
            _intervalTime = new TomatoTime(TimeSpan.FromMilliseconds(workTime), TimeSpan.FromMilliseconds(restTime));
            Init();
        }


        public TomatoTime IntervalTime
        {
            get
            {
                return _intervalTime;
            }
            set
            {
                _intervalTime = value;
                Init();
            }
        }

       

        public void Start()
        {
            _secondTimer.Start();
            IsStarted = true;
        }

        public void Stop()
        {
            _secondTimer.Stop();
            IsStarted = false;
        }

        public void Restart()
        {
            _secondTimer.Stop();
            Init();
            _secondTimer.Start();
        }

        private void Init()
        {
            if (_secondTimer == null)
            {
                _secondTimer = new System.Timers.Timer(1000);
                _secondTimer.AutoReset = true;
                
                _secondTimer.Elapsed += new System.Timers.ElapsedEventHandler(_secondTimer_Elapsed);
            }
            _currentTime = _intervalTime;
            _secondTimer.Stop();
            IsStarted = false;
        }

        void _secondTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (_currentTime.WorkTime>TimeSpan.Zero)
            {
                _currentTime.DecrementWorkTimeSecond();
                if (_currentTime.WorkTime==TimeSpan.Zero)
                {
                    RaiseEndWorkEvent();
                }
            }

            if (_currentTime.WorkTime == TimeSpan.Zero)
            {
                if (_currentTime.RestTime > TimeSpan.Zero)
                {
                    _currentTime.DecrementRestTimeSecond();
                }
                if (_currentTime.RestTime == TimeSpan.Zero)
                {
                    RaiseEndRestEvent();
                }
            }
            if (this.Tick != null)
            {
                Tick(this, new TomatoTimerElapsedEventArgs(_currentTime));
            }
        }

        void RaiseEndWorkEvent()
        {
            _currentTime = new TomatoTime(TimeSpan.FromMilliseconds(0), _intervalTime.RestTime);
            if (this.WorkEnded != null)
            {
                this.WorkEnded(this,EventArgs.Empty);
            }
        }

        void RaiseEndRestEvent()
        {
            _currentTime = new TomatoTime(_intervalTime.WorkTime, TimeSpan.FromMilliseconds(0));
            if (this.RestEnded != null)
            {
                this.RestEnded(this, EventArgs.Empty);
            }
        }
    }

    public class TomatoTimerElapsedEventArgs : EventArgs
    {
        public TomatoTime TimeReminaing
        {
            get;
            private set;
        }
        
        
        public TomatoTimerElapsedEventArgs(TomatoTime _timeRemaining)
        {
            TimeReminaing = _timeRemaining;
        }
    }
}
